'use strict';

const Service = require('egg').Service;

class mod_Service extends Service {
  async findAll(payload) {
    const { ctx } = this;
    let pageStr = '';
    if (payload.limit && payload.skip) {
      pageStr = `skip ${payload.skip} limit ${payload.limit}`;
    }
    const cql = `MATCH (n:${payload.model}) RETURN n ${pageStr}`;
    const { records, summary } = await ctx.app.neo4j.executeQuery(cql, {}, { database: ctx.app.config.database.name });
    return ctx.helper.parseRESEXEC(records);
  }

  async findOne(payload) {
    const { ctx } = this;
    const cql = `MATCH (n:${payload.model}) WHERE n.id = $id RETURN n`;
    const { records, summary } = await ctx.app.neo4j.executeQuery(cql, {id: payload.id}, { database: ctx.app.config.database.name });
    return ctx.helper.parseRESEXEC(records);
  }

  async create(payload) {
    const { ctx } = this;
    payload = ctx.helper.parseParam(ctx, payload);
    const cql = `CREATE (n:${payload.model} $payload) RETURN n`;
    const { records, summary } = await ctx.app.neo4j.executeQuery(cql, {payload: payload}, { database: ctx.app.config.database.name });
    return ctx.helper.parseRESEXEC(records);
  }

  async update(payload) {
    const { ctx } = this;
    const session = ctx.app.neo4j.session();
    const str = ctx.helper.parseCQLup(payload);
    const cql = `
      MATCH (n:${payload.model} {id: "${payload.id}"})
      ${str}
      RETURN n`;
    const result = ctx.helper.parseRES(session, cql);
    return result;
  }

  async add_col(payload) {
    const { ctx } = this;
    const str = ctx.helper.parseCQLup(payload);
    const cql = `
      MATCH (n:${payload.model})
      ${str}
      RETURN n`;
    const { records, summary } = await ctx.app.neo4j.executeQuery(cql, {}, { database: ctx.app.config.database.name });
    return ctx.helper.parseRESEXEC(records);
  }

  async del_col(payload) {
    const { ctx } = this;
    const str = ctx.helper.parseCQLup(payload, true);
    const cql = `
      MATCH (n:${payload.model})
      ${str}
      RETURN n`;
    const { records, summary } = await ctx.app.neo4j.executeQuery(cql, {}, { database: ctx.app.config.database.name });
    return ctx.helper.parseRESEXEC(records);
  }

  async destroy(payload) {
    const { ctx } = this;
    const cql = `
      MATCH (n:${payload.model})
      WHERE n.id IN $ids
      DETACH DELETE n`;
    const { records, summary } = await ctx.app.neo4j.executeQuery(cql, {ids: payload.ids}, { database: ctx.app.config.database.name });
    return records;
  }

  async callDB(payload, cql) {
    const { ctx } = this;
    const { records, summary } = await ctx.app.neo4j.executeQuery(cql, {}, { database: ctx.app.config.database.name });

    let finalRes = [];
    for (const item of records) {
      let obj = {};
      for (const subItem of item.keys) {
        obj[subItem] = item.get(subItem);
      }
      finalRes.push(obj);
    }
    return finalRes;
  }

  async callDBformat(payload, cql) {
    const { ctx } = this;
    const { records, summary } = await ctx.app.neo4j.executeQuery(cql, {}, { database: ctx.app.config.database.name });
    return ctx.helper.parseRESEXEC(records);
  }

  async add_relate(payload) {
    const { ctx } = this;
    const cql = `
      MATCH (a:${payload.model_1}), (b:${payload.model_2})
      WHERE a.id = "${payload.model_1_id}" AND b.id = "${payload.model_2_id}"
      CREATE (a)-[n:${payload.relate}]->(b)
      RETURN n
    `;
    const { records, summary } = await ctx.app.neo4j.executeQuery(cql, {}, { database: ctx.app.config.database.name });
    return ctx.helper.parseRESEXEC(records);
  }

  async del_relate(payload) {
    const { ctx } = this;
    const cql = `
      MATCH (a:${payload.model_1} {id: "${payload.model_1_id}"})-[r:${payload.relate}]->(b:${payload.model_2} {id: "${payload.model_2_id}"})
      DELETE r
    `;
    const { records, summary } = await ctx.app.neo4j.executeQuery(cql, {}, { database: ctx.app.config.database.name });
    return ctx.helper.parseRESEXEC(records);
  }
}

module.exports = mod_Service;
